package com.hdd.utils.wx;


import com.hdd.utils.OSSUtil;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;


/**
 * @author
 * @ClassName: ImageUtil
 * @Description: TODO  图片处理
 */
public class ImageUtil {


    /**
     * 压缩图片
     *
     * @param filePath 目标图片
     * @param suffix   图片扩展名
     * @param level    压缩比例 0~1
     */
    public static String compressImgToString(String filePath, double level, String suffix) {
        StringBuilder destSb = new StringBuilder(filePath);
        try {
            // 读入文件
            File file = new File(filePath);
            // 构造Image对象
            Image img = ImageIO.read(file);
            BufferedImage image = compressImage(img, level);
            destSb.insert(filePath.lastIndexOf("."), "_" + suffix);
            File destFile = new File(destSb.toString());
            FileOutputStream out = new FileOutputStream(destFile);
            ImageIO.write(image, filePath.substring(filePath.indexOf(".") + 1), out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return destSb.toString();
    }

    public static byte[] compressImgToBytes(byte[] imageByte, double level, String suffix) {
        BufferedImage img = null;
        try {
            img = bytesToImage(imageByte);
        } catch (IOException e) {
            e.printStackTrace();
        }
        BufferedImage image = compressImage(img, level);
        return imageToBytes(image, suffix);
    }

    private static BufferedImage compressImage(Image img, double level) {
        if (level > 1 || level < 0) {
            level = 1;
        }
        int width = (int) (img.getWidth(null) * level);
        int height = (int) (img.getHeight(null) * level);

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 创建画布
        Graphics2D g = image.createGraphics();
        //绘制背景透明
        image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g.dispose();
        //创建新的画布
        g = image.createGraphics();
//        g.drawImage(img, 0, 0, width, height, null);
        // SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
        g.drawImage(img.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
        g.dispose();

        return image;
    }

    /**
     * 转换BufferedImage 数据为byte数组
     *
     * @param bImage Image对象
     * @param format image格式字符串.如"gif","png"
     * @return byte数组
     */

    public static byte[] imageToBytes(BufferedImage bImage, String format) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] bytes = null;
        try {
            ImageIO.write(bImage, format, out);
            bytes = out.toByteArray();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    /**
     * 转换byte数组为Image
     *
     * @param bytes
     * @return Image
     */
    private static BufferedImage bytesToImage(byte[] bytes) throws IOException {
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        BufferedImage read = ImageIO.read(in);
        in.close();
        return read;
    }


    /**
     * 打印文字水印图片
     *
     * @param pressText  文字
     * @param targetImg  目标图片
     * @param frontName  字体名
     * @param frontStyle 字体样式
     * @param color      字体颜色
     * @param fontSize   字体大小
     * @param x          x偏移量 选择值从0.0~1.0: 原图的宽度的百分比
     * @param y          y偏移量 选择值从0.0~1.0: 原图的高度的百分比
     * @param alpha      透明度 选择值从0.0~1.0: 完全透明~完全不透明
     */
    private static void pressText(String pressText, BufferedImage src, String targetImg, String frontName, int frontStyle, Color color, int fontSize, float x, float y, float alpha) {
        try {
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);

            g.setColor(color);
            g.setFont(new Font(frontName, frontStyle, fontSize));
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            if (x < 0) {
                x = 0;
            } else if (x > 1) {
                x = 1;
            }
            if (y < 0) {
                y = 0;
            } else if (y > 1) {
                y = 1;
            }
            g.drawString(pressText, (int) (width * x), (int) (height * y));
            g.dispose();

            StringBuilder builder = new StringBuilder(targetImg);
            String suffix = targetImg.substring(targetImg.lastIndexOf(".") + 1);
            File file = new File(builder.insert(targetImg.lastIndexOf("."), "_2").toString());
            ImageIO.write(image, suffix, file);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void pressText(String pressText, String targetImg, String frontName, int frontStyle, Color color, int fontSize, float x, float y, float alpha) {
        try {
            BufferedImage image = ImageIO.read(new File(targetImg));
            pressText(pressText, image, targetImg, frontName, frontStyle, color, fontSize, x, y, alpha);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void pressText(String pressText, byte[] bytes, String targetImg, String frontName, int frontStyle, Color color, int fontSize, float x, float y, float alpha) {
        try {
            BufferedImage image = bytesToImage(bytes);
            pressText(pressText, image, targetImg, frontName, frontStyle, color, fontSize, x, y, alpha);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 为图片添加水印图片
     *
     * @param pressImg  水印图片
     * @param targetImg 目标图片
     * @param alpha     透明度 选择值从0.0~1.0: 完全透明~完全不透明
     */
    public static void pressImage(String pressImg, BufferedImage src, String targetImg, float alpha) {
        try {
            int height = src.getHeight(null);
            int width = src.getWidth(null);
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);

            Image pressImage = ImageIO.read(new File(pressImg));
            int wPress = pressImage.getWidth(null);
            int hPress = pressImage.getHeight(null);

            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            g.drawImage(pressImage, (int) (width * 0.8), (int) (height * 0.1), wPress, hPress, null);
            g.dispose();
            StringBuilder builder = new StringBuilder(targetImg);
            File file = new File(builder.insert(targetImg.lastIndexOf("."), "_2").toString());
            String suffix = targetImg.substring(targetImg.lastIndexOf(".") + 1);
            ImageIO.write(image, suffix, file);
//            FileOutputStream out = new FileOutputStream(builder.insert(targetImg.lastIndexOf("."), "_biao").toString());
//            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//            encoder.encode(image);
//            out.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    public static void pressImage(String pressImg, String targetImg, float alpha) {
        try {
            BufferedImage src = ImageIO.read(new File(targetImg));
            pressImage(pressImg, src, targetImg, alpha);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void pressImage(String pressImg, byte[] bytes, String targetImg, float alpha) {
        try {
            BufferedImage image = bytesToImage(bytes);
            pressImage(pressImg, image, targetImg, alpha);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static String savaByte(String targetImg, byte[] bytes) {
        String url = targetImg;
        try {
            BufferedImage image = bytesToImage(bytes);
            StringBuilder builder = new StringBuilder(targetImg);
            String suffix = targetImg.substring(targetImg.lastIndexOf(".") + 1);
            File file = new File(builder.insert(targetImg.lastIndexOf("."), "_2").toString());
            ImageIO.write(image, suffix, file);
            url = file.getPath().replace(File.separatorChar, '/');
        } catch (IOException e) {
            e.printStackTrace();
        }
        return url;
    }


    /**
     * 生成海报
     *
     * @param paintingUrl 作品url，网络地址
     * @param headPic     作者头像
     * @param author      作者名字
     * @param miniCode    小程序码，二进制数组
     * @return 海报
     */
    public static byte[] drawPoster(String paintingUrl, String headPic, String author, byte[] miniCode){
        byte[] bytes = null;
        try {
            long l1 = System.currentTimeMillis();

            BufferedImage painting = OSSUtil.downloadToImage(paintingUrl);

            // 构造URL
            BufferedImage head;
            try {
                URL url = new URL(headPic);
                head = ImageIO.read(url);
            } catch (IOException e) {
                e.printStackTrace();
                head = ImageIO.read(new URL("https://www.17huaduoduo.com/img/avatars/anonymity.png"));
            }

            long l2 = System.currentTimeMillis();
            System.out.println("读取作品：" + (l2 - l1));

            bytes = drawPoster(painting, head, author, miniCode);

            long l3 = System.currentTimeMillis();
            System.out.println("绘制图片：" + (l3 - l2));
        } catch (Exception e) {
            e.printStackTrace();
        }

        return bytes;
    }

    /**
     * 生成海报
     *
     * @param paintingUrl 作品url，本地
     * @param headPic     作者头像
     * @param author      作者名字
     * @param miniCode    小程序码，本地
     * @param savePath    保存地址，本地
     * @return 海报
     */
    public static String drawPoster(String paintingUrl, String headPic, String author, String miniCode, String savePath) {
        String path = "";
        try {
            String suffix = paintingUrl.substring(paintingUrl.lastIndexOf(".") + 1);
            BufferedImage painting = ImageIO.read(new File(paintingUrl));
            BufferedImage code = ImageIO.read(new File(miniCode));
            BufferedImage head = ImageIO.read(new File(headPic));
            byte[] bytes = drawPoster(painting, head, author, imageToBytes(code, suffix));
            BufferedImage image = bytesToImage(bytes);
//            File file = new File(savePath + "\\" + UUIDGenerator.get() + ".png");
            File file = new File(savePath + "\\" + "3456.png");
            ImageIO.write(image, "png", file);
            path = file.getPath();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return path;
    }


    private static byte[] drawPoster(BufferedImage painting, BufferedImage headPic, String author, byte[] miniCode) {
        byte[] bytes = null;
        try {

            //空白画布宽高
            int canvasWidth = 800;
            int canvasHeight = 260;

            //创建放置头像、文字、小程序码的画布
            BufferedImage blankImage = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D paintingBlank = blankImage.createGraphics();

            //设置填充颜色为白色
            paintingBlank.setColor(Color.WHITE);
//            paintingBlank.setColor(Color.CYAN);
            //填充
            paintingBlank.fillRect(0, 0, canvasWidth, canvasHeight);

            //设置透明度
//            paintingBlank.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1f));

            //绘制头像
            int headPicHeight = (int) (canvasHeight * 0.5);
            int headPicWidth = (int) ((headPic.getWidth(null) / (headPic.getHeight(null) + 0.0)) * headPicHeight);
            int headPicX = (int) (canvasWidth * 0.03);
            int headPicY = (int) (canvasHeight * 0.28);
            paintingBlank.drawImage(headPic.getScaledInstance(headPicWidth, headPicHeight, Image.SCALE_SMOOTH), headPicX, headPicY, null);

            Color color = new Color(64, 64, 64);
            int wordX = headPicX + headPicWidth + 10;
            int wordY = headPicY + 35;

            //绘制作品作者
            paintingBlank.setColor(color);
            paintingBlank.setFont(new Font("宋体", Font.BOLD, 26));
            author = EmojiConvertUtil.recoveryEmoji(author);
            paintingBlank.drawString("@" + author, wordX, wordY);

            paintingBlank.setColor(color);
            paintingBlank.setFont(new Font("黑体", Font.BOLD, 30));
            paintingBlank.drawString("我在画多多发布了新作品", wordX, wordY + 50);

            paintingBlank.setColor(color);
            paintingBlank.setFont(new Font("宋体", Font.BOLD, 28));
            paintingBlank.drawString("长按查看作品详情", wordX, wordY + 90);

            //绘制小程序码
            BufferedImage code = bytesToImage(miniCode);
            int codeWidth = (int) (canvasHeight * 0.65);
            int codeHeight = (int) (canvasHeight * 0.65);
            int codeX = (int) (canvasWidth * 0.74);
            int codeY = (int) (canvasHeight * 0.22);
            paintingBlank.drawImage(code.getScaledInstance(codeWidth, codeHeight, Image.SCALE_SMOOTH), codeX, codeY, null);

            //释放图形上下文使用的系统资源
            paintingBlank.dispose();
            BufferedImage bg = ImageIO.read(new URL("https://www.17huaduoduo.com/img/avatars/picturePosterBg.png"));
            BufferedImage bt = ImageIO.read(new URL("https://www.17huaduoduo.com/img/avatars/picturePosterTitle.png"));

            //作品宽高
            int paintingWidth = painting.getWidth(null);
            int paintingHeight = painting.getHeight(null);

            //空白区域的高度
            int height = (int) ((blankImage.getHeight(null) / (blankImage.getWidth(null) + 0.0)) * paintingWidth);

            //海报宽高
            int posterImageWidth = paintingWidth + 50;
            int posterImageHeight = paintingHeight + height + 140;

            //标题宽高
            int btWidth = (int) (posterImageWidth * 0.5);
            int btHeight = (int) (btWidth * (bt.getHeight(null) / (bt.getWidth(null) + 0.0)));

            //创建海报画布
            BufferedImage poster = new BufferedImage(posterImageWidth, posterImageHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D posterG = poster.createGraphics();

            //绘制背景
            posterG.drawImage(bg.getScaledInstance(posterImageWidth, posterImageHeight, Image.SCALE_SMOOTH), 0, 0, null);

            //绘制标题
            int btX = (posterImageWidth - btWidth) / 2;
            int btY = (posterImageHeight - btHeight - paintingHeight - height) / 2;
            posterG.drawImage(bt.getScaledInstance(btWidth, btHeight, Image.SCALE_SMOOTH), btX, btY, null);

            //绘制作品
            int pX = (posterImageWidth - paintingWidth) / 2;
            int pY = btY + btHeight + 10;
            // SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
            posterG.drawImage(painting.getScaledInstance(paintingWidth, paintingHeight, Image.SCALE_SMOOTH), pX, pY, null);

            //绘制头像、文字、小程序码的空白区域
            posterG.drawImage(blankImage.getScaledInstance(paintingWidth, height, Image.SCALE_SMOOTH), pX, pY + paintingHeight, null);

            //释放图形上下文使用的系统资源
            posterG.dispose();

            bytes = imageToBytes(poster,"png");

        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    /**
     * @param args
     */
    public static void main(String[] args) throws IOException {

        String paintingUrl = "F:\\test\\painting\\c6d7bcdcd261ab746418a9e931bd3f33.png";
        String headPic = "F:\\test\\painting\\132.jpg";
        String author = "小枕头";
        String miniCode = "F:\\test\\painting\\response.jpeg";
        String savePath = "F:\\test\\painting";

        String painting = drawPoster(paintingUrl, headPic, author, miniCode, savePath);
        System.out.println(painting);
    }
}
